package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.user.config.WechatAccountConfig;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.mapper.UserPaidTrackMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;
	@Autowired
	private WechatAccountConfig wechatAccountConfig;
	@Autowired
	private WxMaService wxMaService;
    @Autowired
    private RabbitService rabbitService;
	@Autowired
	private RedisTemplate redisTemplate;
	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;
	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;

	@Override
	public Map<String, Object> wxLogin(String code) {
		//调用微信登录的API
        WxMaJscode2SessionResult wxMaJscode2SessionResult= null;
        try {
            wxMaJscode2SessionResult = wxMaService.jsCode2SessionInfo(code);
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
		//获取openid:每个人微信都对应一个微信标识
        String openid = wxMaJscode2SessionResult.getOpenid();
		//利用openid实现登录注册
		UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid));
		//判断对象是否为空
		if (null==userInfo){
			//说明需要注册---本质上就是赋值
			userInfo=new UserInfo();
			userInfo.setWxOpenId(openid);
			userInfo.setNickname("听友:"+System.currentTimeMillis());
			userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
			//保存数据到数据库
			userInfoMapper.insert(userInfo);
			//在此需要给当前注册的用户进行初始化赋值:同步/异步:mq发送消息
			rabbitService.sendMessage(MqConst.EXCHANGE_USER,MqConst.ROUTING_USER_REGISTER,userInfo.getId());
		}
		//说明要登录,将数据存储到redis中,与返回token
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		//组成缓存的key
		String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX+token;
		//存储数据
		redisTemplate.opsForValue().set(userLoginKey,userInfo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
		//返回数据
		HashMap<String,Object>map=new HashMap<>();
		map.put("token",token);

		return map;
	}

	//获取用户信息
	@Override
	public UserInfoVo getUserInfo(Long userId) {
		//查询用户信息
		UserInfo userInfo=this.getById(userId);
		//创建一个目标对象
		UserInfoVo userInfoVo=new UserInfoVo();
		//属性拷贝
		BeanUtils.copyProperties(userInfo,userInfoVo);
		return userInfoVo;
	}

	//修改用户信息
	@Override
	public void updateUser(Long userId, UserInfoVo userInfoVo) {
		//创建一个对象
		UserInfo userInfo=new UserInfo();
		//属性拷贝
		BeanUtils.copyProperties(userInfoVo,userInfo);
		userInfo.setId(userId);
		this.updateById(userInfo);
	}

	/**
	 * 判断用户是否购买声音列表
	 * @param albumId
	 * @param trackIdList
	 * @param userId
	 * @return
	 */
	@Override
	public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackIdList, Long userId) {
		//创建map集合
		Map<Long, Integer> map = trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 0));
		//判断用户是否购买过专辑：user_paid_album
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>()
				.eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
		if (null != userPaidAlbum) {
			//当前这个用户购买了专辑;
			return trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 1));
		}
		//查询用户购买声音的集合列表;
		List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>()
				.eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList));
		if (!CollectionUtils.isEmpty(userPaidTrackList)) {
			//购买过声音;
			for (UserPaidTrack userPaidTrack : userPaidTrackList) {
				map.put(userPaidTrack.getTrackId(), 1);
			}
		}
		//返回数据：
		return map;
	}

	/**
	 * 判断用户是否购买过专辑
	 * @param userId
	 * @param albumId
	 * @return
	 */
	@Override
	public Boolean isPaidAlbum(Long userId, Long albumId) {
		//查看用户是否购买过专辑
		//先判断用户id是否相同,再判断专辑id是否相同   select id,user_id,album_id from user_paid_album查完之后是当条件用的
		return null !=userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
	}
}
